﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;

namespace YArchitech.Revit
{
	public class HVACDuctUpdater : ElementsUpdater
	{
		public HVACDuctUpdater(Document doc, List<HYUpdateElementInfo> listNodes) : base(doc, listNodes)
		{
		}

		protected override bool Update(string docTitle)
		{
			bool flag = true;
			List<Element> list = new List<Element>();
			Transaction transaction = new Transaction(this.document, "更新数据");
			transaction.Start();
			try
			{
				foreach (HYUpdateElementInfo hyupdateElementInfo in this.nodesToUpdate)
				{
					if (!(hyupdateElementInfo.DocumentTitle == docTitle))
					{
						base.FailedString = "图元所属文档与当前文档不匹配";
						flag = false;
						break;
					}
					Element element = this.document.GetElement(new ElementId(hyupdateElementInfo.ElementID));
					if (element != null)
					{
						if (base.CheckCategory(element, BuiltInCategory.OST_DuctCurves))
						{
							list.Add(element);
							flag &= this.UpdateDuct(element, hyupdateElementInfo);
						}
						else if (base.CheckCategory(element, BuiltInCategory.OST_DuctAccessory))
						{
							flag &= this.UpdateDuctAccessory(element, hyupdateElementInfo);
						}
						else if (base.CheckCategory(element, BuiltInCategory.OST_DuctFitting))
						{
							flag &= this.UpdateDuctFitting(element, hyupdateElementInfo);
						}
					}
				}
				this.document.Regenerate();
				flag = ((int)transaction.Commit() == 3);
				transaction.Start();
				YJKRotateFamilyInstance hyrotateFamilyInstance = new YJKRotateFamilyInstance();
				foreach (Element element2 in list)
				{
					Duct duct = element2 as Duct;
					if (duct != null)
					{
						hyrotateFamilyInstance.MovePiping(duct);
					}
				}
				transaction.Commit();
			}
			catch (Exception ex)
			{
				base.FailedString = ex.ToString();
				flag = false;
			}
			finally
			{
				transaction.GetStatus();
				if (transaction != null && (int)transaction.GetStatus() != 3)
				{
					transaction.RollBack();
					flag = false;
				}
			}
			return flag;
		}

		protected bool UpdateDuct(Element ele, HYUpdateElementInfo eleInfo)
		{
			bool result = false;
			Duct duct = ele as Duct;
			if (duct != null && eleInfo != null)
			{
				if (eleInfo.Shape == HYUpdateElementShape.Round)
				{
					base.SetDistance(ele, BuiltInParameter.RBS_CURVE_DIAMETER_PARAM, eleInfo.Diameter / 1000.0);
				}
				else
				{
					double value = base.GetValue(ele, BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
					double value2 = base.GetValue(ele, BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
					double num = base.DistanceToStd((double)eleInfo.Width / 1000.0);
					double num2 = base.DistanceToStd((double)eleInfo.Height / 1000.0);
					if (value2 > value)
					{
						if (num2 > num)
						{
							base.SetDistance(ele, BuiltInParameter.RBS_CURVE_WIDTH_PARAM, (double)eleInfo.Width / 1000.0);
							base.SetDistance(ele, BuiltInParameter.RBS_CURVE_HEIGHT_PARAM, (double)eleInfo.Height / 1000.0);
						}
						else
						{
							base.SetDistance(ele, BuiltInParameter.RBS_CURVE_WIDTH_PARAM, (double)eleInfo.Height / 1000.0);
							base.SetDistance(ele, BuiltInParameter.RBS_CURVE_HEIGHT_PARAM, (double)eleInfo.Width / 1000.0);
						}
					}
					else if (num2 > num)
					{
						base.SetDistance(ele, BuiltInParameter.RBS_CURVE_WIDTH_PARAM, (double)eleInfo.Height / 1000.0);
						base.SetDistance(ele, BuiltInParameter.RBS_CURVE_HEIGHT_PARAM, (double)eleInfo.Width / 1000.0);
					}
					else
					{
						base.SetDistance(ele, BuiltInParameter.RBS_CURVE_WIDTH_PARAM, (double)eleInfo.Width / 1000.0);
						base.SetDistance(ele, BuiltInParameter.RBS_CURVE_HEIGHT_PARAM, (double)eleInfo.Height / 1000.0);
					}
				}
				result = true;
			}
			return result;
		}

		protected bool UpdateDuctAccessory(Element ele, HYUpdateElementInfo eleInfo)
		{
			bool flag = true;
			FamilyInstance familyInstance = ele as FamilyInstance;
			if (familyInstance != null)
			{
				List<Connector> elementConnectors = base.GetElementConnectors(familyInstance);
				foreach (Connector connector in elementConnectors)
				{
					if (connector.Domain == (Autodesk.Revit.DB.Domain)1)
					{
						flag &= this.UpdateConnector(connector, eleInfo);
					}
				}
			}
			return flag;
		}

		protected bool UpdateDuctFitting(Element ele, HYUpdateElementInfo eleInfo)
		{
			bool result = false;
			FamilyInstance familyInstance = ele as FamilyInstance;
			MechanicalFitting mechanicalFitting = familyInstance.MEPModel as MechanicalFitting;
			HYUpdateAttachedEleInfo hyupdateAttachedEleInfo = eleInfo as HYUpdateAttachedEleInfo;
			if (familyInstance != null && mechanicalFitting != null && hyupdateAttachedEleInfo != null)
			{
                switch ((int)mechanicalFitting.PartType)
				{
				case 5:
					result = this.UpdateElbow(familyInstance, hyupdateAttachedEleInfo);
					break;
				case 6:
					result = this.UpdateTee(familyInstance, hyupdateAttachedEleInfo);
					break;
				case 7:
					result = this.UpdateTrans(familyInstance, hyupdateAttachedEleInfo);
					break;
				case 8:
					result = this.UpdateCross(familyInstance, hyupdateAttachedEleInfo);
					break;
				case 10:
					result = this.UpdateTaper(familyInstance, hyupdateAttachedEleInfo);
					break;
				case 11:
					result = this.UpdateTaper(familyInstance, hyupdateAttachedEleInfo);
					break;
				}
			}
			return result;
		}

		protected bool UpdateTrans(FamilyInstance fi, HYUpdateAttachedEleInfo attachedEleInfo)
		{
			bool flag = true;
			if (fi != null && attachedEleInfo != null)
			{
				List<Connector> elementConnectors = base.GetElementConnectors(fi);
				foreach (Connector connector in elementConnectors)
				{
					Connector connectConnector = base.GetConnectConnector(connector);
					if (connectConnector != null)
					{
						if (attachedEleInfo.InElementInfo != null && connectConnector.Owner.Id.IntegerValue == attachedEleInfo.InElementInfo.ElementID)
						{
							flag &= this.UpdateConnector(connector, attachedEleInfo.InElementInfo);
						}
						if (attachedEleInfo.OutElementInfo != null && connectConnector.Owner.Id.IntegerValue == attachedEleInfo.OutElementInfo.ElementID)
						{
							flag &= this.UpdateConnector(connector, attachedEleInfo.OutElementInfo);
						}
					}
				}
			}
			return flag;
		}

		protected bool UpdateElbow(FamilyInstance fi, HYUpdateAttachedEleInfo attachedEleInfo)
		{
			bool flag = true;
			if (fi != null && attachedEleInfo != null)
			{
				List<Connector> elementConnectors = base.GetElementConnectors(fi);
				if (attachedEleInfo.Horizontal)
				{
					using (List<Connector>.Enumerator enumerator = elementConnectors.GetEnumerator())
					{
						while (enumerator.MoveNext())
						{
							Connector conn = enumerator.Current;
							flag &= this.UpdateConnector(conn, attachedEleInfo.OutElementInfo);
						}
						return flag;
					}
				}
				foreach (Connector conn2 in elementConnectors)
				{
					flag &= this.UpdateConnectorVertical(conn2, attachedEleInfo.OutElementInfo);
				}
			}
			return flag;
		}

		protected bool UpdateTee(FamilyInstance fi, HYUpdateAttachedEleInfo attachedEleInfo)
		{
			bool flag = true;
			if (fi != null && attachedEleInfo != null)
			{
				List<Connector> elementConnectors = base.GetElementConnectors(fi);
				foreach (Connector connector in elementConnectors)
				{
					Connector connectConnector = base.GetConnectConnector(connector);
					if (connectConnector != null)
					{
						if (attachedEleInfo.InElementInfo != null && connectConnector.Owner.Id.IntegerValue == attachedEleInfo.InElementInfo.ElementID)
						{
							flag &= this.UpdateConnector(connector, attachedEleInfo.InElementInfo);
						}
						if (attachedEleInfo.OutElementInfo != null && connectConnector.Owner.Id.IntegerValue == attachedEleInfo.OutElementInfo.ElementID)
						{
							flag &= this.UpdateConnector(connector, attachedEleInfo.OutElementInfo);
						}
						if (attachedEleInfo.SideElementInfo != null && connectConnector.Owner.Id.IntegerValue == attachedEleInfo.SideElementInfo.ElementID)
						{
							flag &= this.UpdateConnector(connector, attachedEleInfo.SideElementInfo);
						}
					}
				}
			}
			return flag;
		}

		protected bool UpdateCross(FamilyInstance fi, HYUpdateAttachedEleInfo attachedEleInfo)
		{
			bool flag = true;
			if (fi != null && attachedEleInfo != null)
			{
				List<Connector> elementConnectors = base.GetElementConnectors(fi);
				foreach (Connector connector in elementConnectors)
				{
					Connector connectConnector = base.GetConnectConnector(connector);
					if (connectConnector != null)
					{
						if (attachedEleInfo.InElementInfo != null && connectConnector.Owner.Id.IntegerValue == attachedEleInfo.InElementInfo.ElementID)
						{
							flag &= this.UpdateConnector(connector, attachedEleInfo.InElementInfo);
						}
						if (attachedEleInfo.OutElementInfo != null && connectConnector.Owner.Id.IntegerValue == attachedEleInfo.OutElementInfo.ElementID)
						{
							flag &= this.UpdateConnector(connector, attachedEleInfo.OutElementInfo);
						}
						if (attachedEleInfo.SideElementInfo != null && connectConnector.Owner.Id.IntegerValue == attachedEleInfo.SideElementInfo.ElementID)
						{
							flag &= this.UpdateConnector(connector, attachedEleInfo.SideElementInfo);
						}
						if (attachedEleInfo.Side2ElementInfo != null && connectConnector.Owner.Id.IntegerValue == attachedEleInfo.Side2ElementInfo.ElementID)
						{
							flag &= this.UpdateConnector(connector, attachedEleInfo.Side2ElementInfo);
						}
					}
				}
			}
			return flag;
		}

		protected bool UpdateTaper(FamilyInstance fi, HYUpdateAttachedEleInfo attachedEleInfo)
		{
			bool result = false;
			if (fi != null && attachedEleInfo != null)
			{
				result = true;
			}
			return result;
		}

		protected bool UpdateConnector(Connector conn, HYUpdateElementInfo eleInfo)
		{
			bool result = false;
			if (conn != null && eleInfo != null)
			{
				try
				{
					if (eleInfo.Shape == HYUpdateElementShape.Round)
					{
						if (conn.Shape == null)
						{
							conn.Radius = base.DistanceToStd(eleInfo.Diameter / 2000.0);
						}
                        else if ((int)conn.Shape == 1)
						{
							conn.Width = base.DistanceToStd(eleInfo.Diameter / 1000.0);
							conn.Height = base.DistanceToStd(eleInfo.Diameter / 1000.0);
						}
					}
					else
					{
						double num = base.DistanceToStd((double)eleInfo.Width / 1000.0);
						double num2 = base.DistanceToStd((double)eleInfo.Height / 1000.0);
						double radius = (num2 > num) ? (num2 / 2.0) : (num / 2.0);
						if (conn.Shape == null)
						{
							conn.Radius = radius;
						}
                        else if ((int)conn.Shape == 1)
						{
							if (conn.Height > conn.Width)
							{
								if (num2 > num)
								{
									conn.Height = num2;
									conn.Width = num;
								}
								else
								{
									conn.Width = num2;
									conn.Height = num;
								}
							}
							else if (num2 < num)
							{
								conn.Height = num2;
								conn.Width = num;
							}
							else
							{
								conn.Width = num2;
								conn.Height = num;
							}
						}
					}
					result = true;
				}
				catch (Exception ex)
				{
					ex.ToString();
				}
			}
			return result;
		}

		protected bool UpdateConnectorVertical(Connector conn, HYUpdateElementInfo eleInfo)
		{
			bool result = false;
			if (conn != null)
			{
				try
				{
					if (eleInfo.Shape == HYUpdateElementShape.Round)
					{
						conn.Radius = base.DistanceToStd(eleInfo.Diameter / 2000.0);
					}
					else
					{
						double num = base.DistanceToStd((double)eleInfo.Width / 1000.0);
						double num2 = base.DistanceToStd((double)eleInfo.Height / 1000.0);
						if (conn.Height > conn.Width)
						{
							if (num2 > num)
							{
								conn.Height = num2;
								conn.Width = num;
							}
							else
							{
								conn.Width = num2;
								conn.Height = num;
							}
						}
						else if (num2 < num)
						{
							conn.Height = num2;
							conn.Width = num;
						}
						else
						{
							conn.Width = num2;
							conn.Height = num;
						}
					}
					result = true;
				}
				catch (Exception ex)
				{
					ex.ToString();
				}
			}
			return result;
		}
	}
}
